﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Babylon.Primitives;
using Babylon.Toolbox;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Silverlight;

namespace Babylon.Toolkit.EffectSystemSample
{
    public partial class MainPage : UserControl
    {
        private OrbitCamera _camera = new OrbitCamera() { Radius = 15 };
        TexturedCubeWithTangents _cube = new TexturedCubeWithTangents(4,4,4);

        // diff, normal/height, heightscale, specularexponent
        List<Tuple<Texture2D, Texture2D, float, float>> _texturePairs = new List<Tuple<Texture2D, Texture2D, float, float>>();

        private ParallaxEffect.ParallaxEffect _effect;
        public MainPage()
        {
            InitializeComponent();
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            var gd = GraphicsDeviceManager.Current.GraphicsDevice;
            _camera.AttachTo(inputSurface);
            _cube.Device = gd;
            _cube.LoadContent();
            _effect = new ParallaxEffect.ParallaxEffect(gd);
            _cube.Effect = _effect;
            _effect.SpecularColor = new Vector3(1,1,1);

            _texturePairs.Add(Tuple.Create(LoadTexture("stones.jpg", gd), LoadTexture("stones_NM_height.png", gd),.02f,60.0f));
            _texturePairs.Add(Tuple.Create(LoadTexture("rocks.jpg", gd), LoadTexture("rocks_NM_height.png", gd), .1f, 100.0f));
            _texturePairs.Add(Tuple.Create(LoadTexture("wall.jpg", gd), LoadTexture("wall_NM_height.png", gd), .06f, 60.0f));
            _texturePairs.Add(Tuple.Create(LoadTexture("wood.jpg", gd), LoadTexture("four_NM_height.png", gd), 0.2f,100.0f));
            _texturePairs.Add(Tuple.Create(LoadTexture("wood.jpg", gd), LoadTexture("saint_NM_height.png", gd), .08f, 100.0f));
            _texturePairs.Add(Tuple.Create(LoadTexture("wood.jpg", gd), LoadTexture("dent_NM_height.png", gd), .2f,100.0f));
        }


        static Texture2D LoadTexture(string resource, GraphicsDevice gd)
        {
            var stream = Application.GetResourceStream(new Uri(resource, UriKind.Relative)).Stream;
            var bmp = new BitmapImage();
            bmp.SetSource(stream);


            Texture2D res = new Texture2D(gd, bmp.PixelWidth, bmp.PixelHeight, false, SurfaceFormat.Color);
            bmp.CopyTo(res);
            return res;
        }

        private void OnAspectRatioChanged(object sender, SizeChangedEventArgs e)
        {
            _camera.AspectRatio = (float)(e.NewSize.Width / e.NewSize.Height);
        }

        private void OnDraw(object sender, DrawEventArgs e)
        {
            var gd = e.GraphicsDevice;
           

            gd.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, new Color(0, 0, 0, 255), 1, 0);

            _effect.Device = gd;
            _cube.Device = gd;
            _effect.CameraPosition = _camera.Position;

            var alpha = _camera.Alpha -0.8f;
            var beta = _camera.Beta + 0.8f;
            var cosa = (float)Math.Cos(alpha);
            var sina = (float)Math.Sin(alpha);
            var cosb = (float)Math.Cos(beta);
            var sinb = (float)Math.Sin(beta);

            var lightPos =  new Vector3( cosa * sinb,  cosb,  sina * sinb);

            _effect.LightDir = Vector3.Normalize(-lightPos);
            _effect.Projection = _camera.Projection;
            _effect.View = _camera.View;

            for(int i=0;i<6;i++)
            {
                var pair = _texturePairs[i];
                _effect.DiffuseTexture = pair.Item1;
                _effect.NormalHeightMapTexture = pair.Item2;
                _effect.HeightScale = pair.Item3;
                _effect.SpecularExponent = pair.Item4;
                _cube.DrawFace(i);
            }

            _camera.ApplyInertia();
            e.InvalidateSurface();
        }
    }
}
